package ie.dkit.java3Demulation.gui;

import ie.dkit.java3Demulation.transforming.Transformable;
import ie.dkit.java3Demulation.transforming.TransformableGroup;
import ie.dkit.java3Demulation.transforming.Transformer;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Collection;
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class ControllButtonDialog extends JDialog implements ActionListener {

	private abstract class Agent extends Thread {
		private boolean continous;

		public Agent(boolean continous) {
			this.continous = continous;
			start();
		}

		public void run() {
			do {
				doJob();
				synchronized (this) {
					try {
						try {
							long interval = Long.parseLong(changeIntervall
									.getText());
							wait(interval);
						} catch (NumberFormatException e) {
							e.printStackTrace();
							changeIntervall.setText("" + 1000);
							wait(1000);
						}
					} catch (InterruptedException e) {
						return;
					}
				}
			} while (continous && !this.isInterrupted());
		}

		public abstract void doJob();
	}

	/**
	 * 
	 */
	private static final long serialVersionUID = 1969843992704390136L;

	private static Collection<Agent> agents = new Vector<Agent>();

	private TransformableGroup m_Transformables;

	private JButton rotateLeft, rotateRight, rotateUp, rotateDown, rollLeft,
			rollRight, moveUp, moveDown, moveLeft, moveRight, moveBack,
			moveForward, scaleXP, scaleXM, scaleYP, scaleYM, scaleZP, scaleZM;

	private JTextField rotateSpeed;

	private JTextField moveSpeed;

	private JCheckBox continousCheckBox;

	private JTextField changeIntervall;

	private JButton killdeamon;

	public ControllButtonDialog(Transformable transformable) {
		TransformableGroup transformables = new TransformableGroup();
		transformables.add(transformable);
		init("Controller for: " + transformable.getName(), transformables);
	}

	public ControllButtonDialog(String title, TransformableGroup transformables) {
		init(title, transformables);
	}

	private void init(String title, TransformableGroup transformables) {
		m_Transformables = transformables;
		setTitle(title);
		JPanel content = new JPanel();
		content.setLayout(new GridBagLayout());

		GridBagConstraints gridC = new GridBagConstraints();
		gridC.gridx = 0;
		gridC.gridy = 0;
		content.add(new JLabel("Rotating:"), gridC);
		JPanel panel = new JPanel();
		panel.setLayout(new BorderLayout());
		panel.add(rotateLeft = new JButton("Left"), BorderLayout.WEST);
		rotateLeft.addActionListener(this);
		panel.add(rotateRight = new JButton("Right"), BorderLayout.EAST);
		rotateRight.addActionListener(this);
		panel.add(rotateUp = new JButton("Up"), BorderLayout.NORTH);
		rotateUp.addActionListener(this);
		panel.add(rotateDown = new JButton("Down"), BorderLayout.SOUTH);
		rotateDown.addActionListener(this);
		panel.add(rotateSpeed = new JTextField("5"), BorderLayout.CENTER);

		gridC = new GridBagConstraints();
		gridC.gridx = 0;
		gridC.gridy = 1;
		content.add(panel, gridC);
		panel = new JPanel();
		panel.add(rollLeft = new JButton("Roll left"));
		rollLeft.addActionListener(this);
		panel.add(rollRight = new JButton("Roll right"));
		rollRight.addActionListener(this);

		gridC = new GridBagConstraints();
		gridC.gridx = 0;
		gridC.gridy = 2;
		content.add(panel, gridC);

		gridC = new GridBagConstraints();
		gridC.gridx = 0;
		gridC.gridy = 3;
		content.add(new JLabel("Moving:"), gridC);

		panel = new JPanel();
		panel.setLayout(new BorderLayout());
		panel.add(moveLeft = new JButton("Left"), BorderLayout.WEST);
		moveLeft.addActionListener(this);
		panel.add(moveRight = new JButton("Right"), BorderLayout.EAST);
		moveRight.addActionListener(this);
		panel.add(moveUp = new JButton("Up"), BorderLayout.NORTH);
		moveUp.addActionListener(this);
		panel.add(moveDown = new JButton("Down"), BorderLayout.SOUTH);
		moveDown.addActionListener(this);
		panel.add(moveSpeed = new JTextField("5"), BorderLayout.CENTER);

		gridC = new GridBagConstraints();
		gridC.gridx = 0;
		gridC.gridy = 4;
		content.add(panel, gridC);

		panel = new JPanel();
		panel.add(moveBack = new JButton("Move back"));
		moveBack.addActionListener(this);
		panel.add(moveForward = new JButton("Move forward"));
		moveForward.addActionListener(this);

		gridC = new GridBagConstraints();
		gridC.gridx = 0;
		gridC.gridy = 5;
		content.add(panel, gridC);

		panel = new JPanel();
		panel.setLayout(new GridLayout(2, 3));
		panel.add(scaleXP = new JButton("X+"));
		scaleXP.addActionListener(this);
		panel.add(scaleYP = new JButton("Y+"));
		scaleYP.addActionListener(this);
		panel.add(scaleZP = new JButton("Z+"));
		scaleZP.addActionListener(this);
		panel.add(scaleXM = new JButton("X-"));
		scaleXM.addActionListener(this);
		panel.add(scaleYM = new JButton("Y-"));
		scaleYM.addActionListener(this);
		panel.add(scaleZM = new JButton("Z-"));
		scaleZM.addActionListener(this);

		gridC = new GridBagConstraints();
		gridC.gridx = 0;
		gridC.gridy = 6;
		content.add(panel, gridC);

		gridC = new GridBagConstraints();
		gridC.gridx = 0;
		gridC.gridy = 7;
		content.add(new JLabel("Auto Pilot:"), gridC);
		panel = new JPanel();
		panel.add(continousCheckBox = new JCheckBox("Continous"));
		panel.add(changeIntervall = new JTextField("100"));
		panel.add(killdeamon = new JButton("Kill all continous Agent"));
		killdeamon.addActionListener(this);

		gridC = new GridBagConstraints();
		gridC.gridx = 0;
		gridC.gridy = 8;
		content.add(panel, gridC);
		add(content);
		pack();
		setVisible(true);
	}

	public void actionPerformed(ActionEvent e) {
		final double roationSpeed;
		final double movingSpeed;
		boolean continous = continousCheckBox.isSelected();
		try {
			roationSpeed = Double.parseDouble(rotateSpeed.getText());
			movingSpeed = Double.parseDouble(moveSpeed.getText());
		} catch (NumberFormatException nu) {
			JOptionPane.showMessageDialog(null, "Only float are allowes",
					"NumberFormatException", JOptionPane.ERROR_MESSAGE);
			return;
		}
		if (e.getSource().equals(rotateLeft)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.rotateY(m_Transformables, roationSpeed);
				}
			});
		} else if (e.getSource().equals(rotateRight)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.rotateY(m_Transformables, -roationSpeed);
				}
			});
		} else if (e.getSource().equals(rotateUp)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.rotateX(m_Transformables, roationSpeed);
				}
			});
		} else if (e.getSource().equals(rotateDown)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.rotateX(m_Transformables, -roationSpeed);
				}
			});
		} else if (e.getSource().equals(rollLeft)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.rotateZ(m_Transformables, roationSpeed);
				}
			});
		} else if (e.getSource().equals(rollRight)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.rotateZ(m_Transformables, -roationSpeed);
				}
			});
		} else if (e.getSource().equals(moveUp)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.translate(m_Transformables, 0, movingSpeed, 0);
				}
			});
		} else if (e.getSource().equals(moveDown)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.translate(m_Transformables, 0, -movingSpeed, 0);
				}
			});
		} else if (e.getSource().equals(moveLeft)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.translate(m_Transformables, -movingSpeed, 0, 0);
				}
			});
		} else if (e.getSource().equals(moveRight)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.translate(m_Transformables, movingSpeed, 0, 0);
				}
			});
		} else if (e.getSource().equals(moveBack)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.translate(m_Transformables, 0, 0, movingSpeed);
				}
			});
		} else if (e.getSource().equals(moveForward)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.translate(m_Transformables, 0, 0, -movingSpeed);
				}
			});
		} else if (e.getSource().equals(scaleXP)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.scale(m_Transformables, 2, 1, 1);
				}
			});
		} else if (e.getSource().equals(scaleXM)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.scale(m_Transformables, 0.5, 1, 1);
				}
			});
		} else if (e.getSource().equals(scaleYP)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.scale(m_Transformables, 1, 2, 1);
				}
			});
		} else if (e.getSource().equals(scaleYM)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.scale(m_Transformables, 1, 0.5, 1);
				}
			});
		} else if (e.getSource().equals(scaleZP)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.scale(m_Transformables, 1, 1, 2);
				}
			});
		} else if (e.getSource().equals(scaleZM)) {
			agents.add(new Agent(continous) {
				public void doJob() {
					Transformer.scale(m_Transformables, 1, 1, 0.5);
				}
			});
		} else if (e.getSource().equals(killdeamon)) {
			for (Thread t : agents) {
				t.interrupt();
			}
		}
	}
}
